# coding:utf-8

import time
from utils_lib.utils import sum256_hex


# Block header class 块头类
# by liang fei 2021.06.28


# class: BlockHeader
# the block header
# Attributes:
#     timestamp (str): 时间戳 创建块头对象时的时间
#     prev_block_hash (str): 上一块的hash
#     block_hash (str): 当前块的hash
#     hash_merkle_root (str): Hash of the merkle_root
#     reputation_threshold (int): 信誉值 阈值
#     reputation (int): 当前块的信誉值
#     height (int): 块高度
class BlockHeader(object):

    # 静态类变量 reputation_threshold 和 reputation 可在此全局修改默认值
    DEFAULT_VALUE_REPUTATION_THRESHOLD = '1'
    DEFAULT_VALUE_REPUTATION = '1'

    # func: 构建函数 创建BlockHeader对象
    # @param: hash_merkle_root (str): merkle树的hash
    #         height (int): 块高度
    #         pre_block_hash (str): 缺省为空 上一块的hash
    #         reputation_threshold (int): 缺省值为1 信誉阈值
    #         reputation (int): 缺省值为1 当前块的信誉值
    # return: BlockHeader Object
    def __init__(self, hash_merkle_root, height, prev_block_hash='',
                 reputation_threshold=DEFAULT_VALUE_REPUTATION_THRESHOLD,
                 reputation=DEFAULT_VALUE_REPUTATION):

        self.timestamp = str(time.time())  # 时间戳
        self.prev_block_hash = prev_block_hash  # 上一块的hash
        self.block_hash = None  # 当前块的hash 既不需要输入也不需要默认值 后续会计算
        self.hash_merkle_root = hash_merkle_root  # merkle树的hash
        self.reputation_threshold = reputation_threshold  # 缺省值输入
        self.reputation = reputation  # 缺省值输入
        self.cnrp = {}
        self.height = height  # 块高度
        self.nonce = None

    # func: 类方法 利用构建函数创建新的创世块
    # @param: none
    # return: BlockHeader Object
    @classmethod
    def new_genesis_block_header(cls):
        return cls('', 0)

    def set_cnrp(self, _cnrp):
        self.cnrp = _cnrp

    # func: 计算当前header的哈希值 并填充于本对象中的block_hash变量中
    # @param: none
    # return: none
    def set_hash(self):
        header_hash_params = [str(self.timestamp),
                              str(self.prev_block_hash),
                              str(self.hash_merkle_root),
                              str(self.height),
                              str(self.nonce)]
        header_hash_params = ''.join(header_hash_params)
        self.block_hash = sum256_hex(header_hash_params)

    # func: 序列化当前对象内容 工具类函数
    # @param: none
    # return: none
    def serialize(self):
        return self.__dict__

    # func: 类方法 反序列化 格式转化 dict --> BlockHeader Object
    # @param: header_dict (dict): BlockHeader dict 块头在db中的存储形式
    # return: BlockHeader Object
    @classmethod
    def deserialize(cls, header_dict):
        timestamp = header_dict.get('timestamp', '')
        prev_block_hash = header_dict.get('prev_block_hash', '')
        block_hash = header_dict.get('block_hash', '')
        hash_merkle_root = header_dict.get('hash_merkle_root', '')
        reputation_threshold = header_dict.get('reputation_threshold', cls.DEFAULT_VALUE_REPUTATION_THRESHOLD)
        reputation = header_dict.get('reputation', cls.DEFAULT_VALUE_REPUTATION)
        cnrp = header_dict.get('cnrp', {})
        height = header_dict.get('height', '')
        nonce = header_dict.get('nonce', '')

        block_header = cls(hash_merkle_root, height, prev_block_hash, reputation_threshold, reputation)
        block_header.timestamp = timestamp
        block_header.block_hash = block_hash
        block_header.nonce = nonce
        block_header.cnrp = cnrp
        return block_header

    # func: 序列化 格式转化 BlockHeader Object --> dict
    # @param: none
    # return: BlockHeader dict
    def __repr__(self):
        header_str = 'BlockHeader(timestamp={0!r}, prev_block_hash={1!r}, block_hash={2!r}, hash_merkle_root={3!r}, ' \
                     'reputation_threshold={4!r}, reputation={5!r}, height={6!r}), cnrp={7!r} '
        return header_str.format(self.timestamp, self.prev_block_hash, self.block_hash, self.hash_merkle_root,
                                 self.reputation_threshold, self.reputation, self.height, str(self.cnrp))




